#include <stdio.h>
#include "main.h"
#include "mem.h"
#include "uart.h"
#include "funcBlock.h"
#include "funcBlock_NET.h"

extern uint8_t in_port_used;
extern uint8_t out_port_used;

struct fb_NET
{
	uint8_t type;
	function_t func;
	uint8_t in0;
	uint8_t out0;
};

// ****************** FunctionBlock NET 1xIn 1xOut *******************

void function_fb_NET(struct funcBlock_t *_fb)
{
	struct fb_NET *fb = (struct fb_NET*)_fb;

	setState(fb->out0, getState(fb->in0));
}

void function_fb_INPUT(struct funcBlock_t *_fb)
{
	struct fb_NET *fb = (struct fb_NET*)_fb;

	setState(fb->out0, getStateInput(fb->in0));
}

void function_fb_OUTPUT(struct funcBlock_t *_fb)
{
	struct fb_NET *fb = (struct fb_NET*)_fb;

	setStateOutput(fb->out0, getState(fb->in0));
}

void function_fb_ANALOG_INPUT(struct funcBlock_t *_fb)
{
	struct fb_NET *fb = (struct fb_NET*)_fb;

	setBusValue_16b(fb->out0, getAnalogInputValue_16b(fb->in0));
}

void function_fb_ANALOG_OUTPUT(struct funcBlock_t *_fb)
{
	struct fb_NET *fb = (struct fb_NET*)_fb;

	setAnalogOutputValue_16b(fb->out0, getBusValue_16b(fb->in0));
}

/*
struct fb_NET* get_fb_NET()
{
	struct fb_NET *fb;

	fb = (struct fb_NET*)getMem(sizeof(struct fb_NET));
	if (fb != NULL)
	{
		//fb->type = FB_TYPE_NET;
		fb->func = function_fb_NET;
	}
	return fb;
}
*/

struct funcBlock_t* get_fb_INPUT(uint8_t input, uint8_t net)
{
	struct fb_NET *fb = NULL;

	if ((input < NUM_INPUTS) && (net < NUM_1BIT_STATES))
	{
		fb = (struct fb_NET*)getMem(sizeof(struct fb_NET));
		if (fb != NULL)
		{
			in_port_used |= (1 << (input/8));
			//uart_puts("INPUT\n");
			fb->type = FB_TYPE_INPUT;
			fb->func = function_fb_INPUT;
			fb->in0 = input;
			fb->out0 = net;
		}
	}
	return (struct funcBlock_t*)fb;
}

struct funcBlock_t* get_fb_OUTPUT(uint8_t output, uint8_t net)
{
	struct fb_NET *fb = NULL;

	if ((output < NUM_OUTPUTS) && (net < NUM_1BIT_STATES))
	{
		fb = (struct fb_NET*)getMem(sizeof(struct fb_NET));
		if (fb != NULL)
		{
			out_port_used |= (1 << (output/8));
			//uart_puts("OUTPUT\n");
			fb->type = FB_TYPE_OUTPUT;
			fb->func = function_fb_OUTPUT;
			fb->out0 = output;
			fb->in0 = net;
		}
	}
	return (struct funcBlock_t*)fb;
}

struct funcBlock_t* get_fb_ANALOG_INPUT(uint8_t input, uint8_t net)
{
	struct fb_NET *fb = NULL;

	if ((input < NUM_ANALOG_INPUTS) && (net < NUM_16BIT_BUS))
	{
		fb = (struct fb_NET*)getMem(sizeof(struct fb_NET));
		if (fb != NULL)
		{
			//uart_puts("ANALOG_INPUT\n");
			fb->type = FB_TYPE_ANALOG_INPUT;
			fb->func = function_fb_ANALOG_INPUT;
			fb->in0 = input;
			fb->out0 = net;
		}
	}
	return (struct funcBlock_t*)fb;
}

struct funcBlock_t* get_fb_ANALOG_OUTPUT(uint8_t output, uint8_t net)
{
	struct fb_NET *fb = NULL;

	if ((output < NUM_ANALOG_OUTPUTS) && (net < NUM_16BIT_BUS))
	{
		fb = (struct fb_NET*)getMem(sizeof(struct fb_NET));
		if (fb != NULL)
		{
			//uart_puts("OUTPUT\n");
			fb->type = FB_TYPE_ANALOG_OUTPUT;
			fb->func = function_fb_ANALOG_OUTPUT;
			fb->out0 = output;
			fb->in0 = net;
		}
	}
	return (struct funcBlock_t*)fb;
}
